package com.alogic.load;

import com.alogic.xscript.*;
import com.alogic.xscript.doc.XsObject;
import com.alogic.xscript.doc.json.JsonObject;
import com.anysoft.util.*;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Element;

import java.util.HashMap;

/**
 * 通用Loadable对象加载器
 * @since 1.6.13.17 [20200923 duanyy] <br>
 */
public class CommonObjectHotLoader extends Loader.Hot<CommonObject>{
    /**
     * 加载事件脚本
     */
    protected Logiclet onLoad = null;

    protected static final String ID_LOADER = "$common-loader";

    protected static final String ID_LAST_SCAN_TIME = "$lastScanTime";

    protected long lastScanTime = 0;

    @Override
    public void configure(Properties p){
        super.configure(p);
    }

    @Override
    public void configure(Element e, Properties p) {
        Properties props = new XmlElementProperties(e,p);

        Element onLoadElem = XmlTools.getFirstElementByPath(e, "on-load");
        if (onLoadElem != null){
            onLoad = Script.create(onLoadElem, props);
        }

        configure(props);
    }

    @Override
    protected synchronized void doLoad(boolean first) {
        if (onLoad != null){
            LogicletContext logicletContext = new LogicletContext(Settings.get());
            try {
                logicletContext.setObject(ID_LOADER,this);
                logicletContext.SetValue(ID_LAST_SCAN_TIME,String.valueOf(this.lastScanTime));
                XsObject doc = new JsonObject("root",new HashMap<String,Object>());
                onLoad.execute(doc,doc, logicletContext, null);
                lastScanTime = System.currentTimeMillis();
            }finally{
                logicletContext.removeObject(ID_LOADER);
            }
        }
    }

    /**
     * 新增一个对象
     */
    public static class ObjectFound extends AbstractLogiclet {

        /**
         * 　对象id
         */
        protected String $id = "";

        public ObjectFound(String tag, Logiclet p) {
            super(tag, p);
        }

        @Override
        public void configure(Properties p){
            super.configure(p);
            $id = PropertiesConstants.getRaw(p, "id", "");
        }

        @Override
        protected void onExecute(XsObject root,XsObject current, LogicletContext ctx,
                                 ExecuteWatcher watcher) {
            CommonObjectHotLoader loader = ctx.getObject(ID_LOADER);
            if (loader != null){
                String id = PropertiesConstants.transform(ctx,$id,"");
                if (StringUtils.isNotEmpty(id)){
                    CommonObject obj = new CommonObject(id);
                    loader.add(id,obj);
                }
            }
        }
    }

    /**
     * 删除一个对象
     */
    public static class ObjectRemove extends AbstractLogiclet {

        /**
         * 　对象id
         */
        protected String $id = "";

        public ObjectRemove(String tag, Logiclet p) {
            super(tag, p);
        }

        @Override
        public void configure(Properties p){
            super.configure(p);
            $id = PropertiesConstants.getRaw(p, "id", "");
        }

        @Override
        protected void onExecute(XsObject root,XsObject current, LogicletContext ctx,
                                 ExecuteWatcher watcher) {
            CommonObjectHotLoader loader = ctx.getObject(ID_LOADER);
            if (loader != null){
                String id = PropertiesConstants.transform(ctx,$id,"");
                if (StringUtils.isNotEmpty(id)){
                    loader.remove(id);
                }
            }
        }
    }
}
